"""
生成带啊吗。
MySQL
GraphQL
FLask

作者：修炼者 7457222@qq.com
日期: 2024-12-10 10:48:19
"""
from public.Task import Task
from public.jygt_coder_loger import get_logger

logger = get_logger(__name__)


import  public.jygt_coder_utitls as JygtCoderUtitls

from mako.lookup import TemplateLookup
from mako.template import Template
from mako.exceptions import TemplateLookupException, SyntaxException

mako_template_dir = JygtCoderUtitls.get_coder_template_dir()
lookup = TemplateLookup(directories=[
    mako_template_dir
    ])

def generate_entity_code(table_name, columns):
    template = lookup.get_template('entity.mako')
    return template.render(table_name=table_name, columns=columns)

def generate_service_code(table_name, columns,indexes):
    template = lookup.get_template('service.mako')
    return template.render(table_name=table_name, columns=columns,indexes=indexes)   

def generate_connection_code(conn_str:str)->str:
    template = lookup.get_template('connection.mako')
    return template.render(conn_str=conn_str)

def generate_test_code(table_name, columns,indexes):    
    template = lookup.get_template('test.mako')
    return template.render(table_name=table_name, columns=columns,indexes=indexes)
    
def generate_main_code(db_name, host,port,prefix):    
    template = lookup.get_template('main.mako')
    return template.render(db_name=db_name, host=host,port=port,prefix=prefix)

def generate_iql_code(prefix):    
    template = lookup.get_template('graphql_customer_iql.mako')
    return template.render(prefix=prefix)


def generate_graphql_object_code(table_name, columns,indexes):    
    template = lookup.get_template('graphql_object.mako')
    return template.render(table_name=table_name, columns=columns,indexes=indexes)
    
def generate_graphql_query_code(table_name, columns,indexes):    
    template = lookup.get_template('graphql_query.mako')
    return template.render(table_name=table_name, columns=columns,indexes=indexes)
    
def generate_graphql_mutation_code(table_name, columns,indexes):    
    template = lookup.get_template('graphql_mutation.mako')
    return template.render(table_name=table_name, columns=columns,indexes=indexes)
    
def generate_graphql_schema_code(db_name,table_infos):    
    template = lookup.get_template('graphql_schema.mako')
    return template.render(db_name=db_name, table_infos=table_infos)
    
    

def generateCode(task_info:Task)->bool:
    res = False
    try:
        objTPInfo = task_info.getTargetProjectInfo()
        # 1. 生成连接池代码
        code_connection = generate_connection_code(task_info.getDBInfo().getSQLAlchemyConnectionString())

        objTPInfo.save(
            code_connection,
            JygtCoderUtitls.get_connection_file_name(), 
            objTPInfo.getDirOfSrc(JygtCoderUtitls.get_connection_file_directory())
        )
        
        # 2. 循环生成 实体类 服务类 服务类的测试代码
        table_info = task_info.getDBInfo().getInfo()
        for itm in table_info:
            # 2.1 生成实体代码
            code_entity = generate_entity_code(itm["table_name"],itm["columns"])
            objTPInfo.save(
                code_entity,
                JygtCoderUtitls.get_entity_file_name(itm["table_name"]),
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_entity_file_directory()) 
            )
            # 2.2 生成服务代码
            code_service = generate_service_code(itm["table_name"],itm["columns"],itm["indexes"])
            objTPInfo.save(
                code_service,
                JygtCoderUtitls.get_service_file_name(itm["table_name"]),
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_service_file_directory()) 
            )
            # 2.3 生成测试代码
            code_test = generate_test_code(itm["table_name"],itm["columns"],itm["indexes"])
            objTPInfo.save(
                code_test,
                JygtCoderUtitls.get_test_file_name(itm["table_name"]),
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_test_file_directory())
            )
        
            # 3. 生成GraphQL代码: 
            # 3.1 object
            code_graphql_object = generate_graphql_object_code(itm["table_name"],itm["columns"],itm["indexes"])

            objTPInfo.save(
                code_graphql_object,
                JygtCoderUtitls.get_graphql_object_file_name(itm["table_name"]), 
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_grapql_object_file_directory())
            )
            # 3.2 query
            code_graphql_query = generate_graphql_query_code(itm["table_name"],itm["columns"],itm["indexes"])

            objTPInfo.save(
                code_graphql_query,
                JygtCoderUtitls.get_graphql_query_file_name(itm["table_name"]), 
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_grapql_query_file_directory())
            )
            # 3.3 mutation
            code_graphql_mutation = generate_graphql_mutation_code(itm["table_name"],itm["columns"],itm["indexes"])

            objTPInfo.save(
                code_graphql_mutation,
                JygtCoderUtitls.get_graphql_mutation_file_name(itm["table_name"]), 
                objTPInfo.getDirOfSrc(JygtCoderUtitls.get_grapql_mutation_file_directory())
            )

        # 3.4 schema
        code_graphql_schema = generate_graphql_schema_code(
            task_info.getDBInfo().getDatabase(),
             task_info.getDBInfo().getInfo()
        )

        objTPInfo.save(
            code_graphql_schema,
            JygtCoderUtitls.get_graphql_schema_file_name(task_info.getDBInfo().getDatabase()), 
            objTPInfo.getDirOfSrc(JygtCoderUtitls.get_graphql_schema_file_directory())
        )

        # 3.5. 生成iql入口代码: templates/customer_graphiql.html  
        code_iql = generate_iql_code(
            prefix=task_info.getWebAPIInfo().getPath()
        )

        objTPInfo.save(
            code_iql,
            JygtCoderUtitls.get_graphql_customer_iql_file_name(), 
            objTPInfo.getDirOfSrc(JygtCoderUtitls.get_graphql_customer_iql_file_directory())
        )
        # 4. 生成入口代码: main.py    
        code_main = generate_main_code(task_info.getDBInfo().getDatabase(),
                        host=task_info.getWebAPIInfo().getHost(),
                        port=task_info.getWebAPIInfo().getPort(),
                        prefix=task_info.getWebAPIInfo().getPath()
               )

        objTPInfo.save(
            code_main,
            JygtCoderUtitls.get_main_file_name(), 
            objTPInfo.getDirOfSrc()
        )
        
        res = True

    except TemplateLookupException as e:
        logger.error(f"Template not found: {e}")
        res = False

    except SyntaxException as e:
        logger.error(f"Syntax error in template: {e}")
        res = False

    except Exception as e:
        logger.error(f"An error occurred: {e}")
        res = False
    finally:
        return res
